'''
2,分簇
'''
import random
from scipy.io import loadmat
import numpy as np
from LearnPy.MIClustering.MyBamic.bag_dist_matrix import bag_dist_matrix




def bamic(musk,k,dist_matrix):
    """
    :param musk: 训练集
    :param k: 聚类后k的数量
    :param dist_matrix:包与包的距离矩阵
    :return:返回包与簇中心的距离矩阵
        bag_center_dist矩阵用于存储包到簇中心的距离
        bag_center_dist[i,j]表示包i到簇中心j的距离
        bag_center_dist[i,k+1]表示该包的label
        bag_center_dist[bag_num][i]表示第i个簇中心的索引
    """
    '''
    优化解决办法，输出簇中心的索引，
    使用bag_center_dist[bag_num][i]表示第i个簇中心的索引
    成功耶耶耶
    '''

    bag_num = len(musk['data'])
    #为了取k个不同的随机数，打乱一下数组
    random_k = list(range(0,bag_num-1))
    random.shuffle(random_k)
    '''
    使用矩阵存储 簇 
    cluster[i][n] 表示第i个簇的簇中心的索引
    cluster[i][0]到cluster[i][n-1] 为一个簇中所有包的索引
    包的索引从0到n-1
    初始化矩阵的各项值为-1
    '''
    cluster = np.empty((k,bag_num+1),int)
    for i in range(0,k):
        for j  in range(0,bag_num+1):
            cluster[i,j] = -1

    #随机的簇中心
    for i in range(0,k):
        cluster[i,bag_num] = random_k[i]



    #标记本次分簇是否改变，未改变为0 ，已改变为1
    change = 1

    #多次循环确立簇中心
    while change == 1:#如果上次分簇改变，继续分簇
        change = 0

        for i in range(0,k):#清空每个包的簇中心的索引数据
            for j in range(0,bag_num):
                cluster[i,j]=-1

        #根据簇中心分簇
        for i in range(0,bag_num):
            min_distanc_index = cluster[0,bag_num]#距离此包的最近的簇中心的索引，先假设等于第一个簇中心吧
            min_distanc_index_j = 0


            for j in range(0,k):

                if dist_matrix[i,min_distanc_index] > dist_matrix[i,cluster[j,bag_num]]:
                    #就是这里出的错dist_matrix不能出现92
                    min_distanc_index = cluster[j,bag_num]
                    min_distanc_index_j = j

            cluster[min_distanc_index_j,i] = i

        #重新确立簇中心
        for p in range(0,k):#k个簇
            min_distanc = np.zeros(bag_num)


            for i in range(0,bag_num):#i个包
                if cluster[p,i] != -1:
                    for j in range(0,bag_num-1):#与其他j个包距离相加
                        if cluster[p,j] != -1:
                            min_distanc[i] += dist_matrix[i,j]
            #找簇中心------找到距离最小的索引
            min  = 0
            min_index = 0
            for i in range(0,bag_num):
                if min == 0:
                    min = min_distanc[i]
                    min_index = i
                elif(min>min_distanc[i] and min_distanc[i] !=0 ):
                    min_index = i
                    min =  min_distanc[i]



            if(cluster[p,bag_num]!=min_index):
                change = 1
                cluster[p,bag_num] = min_index


    """
    bag_center_dist矩阵用于存储包到簇中心的距离
    bag_center_dist[i,j]表示包i到簇中心j的距离
    bag_center_dist[i,k+1]表示该包的label
    """
    bag_center_dist =np.empty((bag_num+1,k),float)
    for i in range(0,bag_num):
        #bag_center_dist[i,k] = musk["data"][i][1]
        for j in range(0,k):
            bag_center_dist[i,j] = dist_matrix[i,cluster[j,bag_num]]

    for i in range(k):
        bag_center_dist[bag_num][i] = cluster[i][bag_num]
    print(cluster[:,bag_num])



    return bag_center_dist



if __name__=="__main__":
    path = './musk33.mat'
    musk1 = loadmat(path)
    bamic(musk1,3,bag_dist_matrix(musk1))



